/**
 * 曲线
 */
export class Curve {
  private curveFunc: (x: number) => number;
  public xRange: number[];
  public yRange: number[];
  constructor(
    curveFunc: (x: number) => number,
    xRange: number[],
    yRange: number[]
  ) {
    this.curveFunc = curveFunc;
    this.xRange = xRange;
    this.yRange = yRange;
  }

  /**根据函数获取y值；
   * 有y值的取值范围
   * @param x
   * @returns
   */
  getY(x: number) {
    let y = this.curveFunc(x);
    if (x < this.xRange[0]) {
      y = this.curveFunc(this.xRange[0]);
    } else if (x > this.xRange[1]) {
      y = this.curveFunc(this.xRange[1]);
    }
    if (y < this.yRange[0]) {
      y = this.yRange[0];
    } else if (y > this.yRange[1]) {
      y = this.yRange[1];
    }
    return y;
  }
}

function f(x: number) {
  return Math.sin(x);
}

const wave = new Curve((x) => Math.sin(x), [0, 3 * Math.PI], [-1, 1]);

/** 根据函数布局Dom集合元素
 *
 * @param curve
 * @param doms Dom集合元素
 * @param width 宽度
 * @param height 高度
 */
function layout(
  curve: Curve,
  doms: HTMLElement[],
  width: number,
  height: number
) {
  const [xmin, xmax] = curve.xRange;
  const [ymin, ymax] = curve.yRange;
  //中心线坐标
  const cx = (xmin + xmax) / 2;
  const cy = (ymin + ymax) / 2;
  //放大系数
  const scaleX = width / (xmax - xmin);
  const scaleY = height / (ymax - ymin);
  //根据元素数量算x步长
  const step = (xmax - xmin) / (doms.length - 1);

  for (let i = 0; i < doms.length; i++) {
    const dom = doms[i];
    //曲线坐标系坐标
    const x = xmin + i * step;
    const y = curve.getY(x);
    //实际坐标系坐标
    const dx = (x - cx) * scaleX;
    const dy = (y - cy) * scaleY;
    //设置dom元素属性值
    dom.style.setProperty("--dx", String(dx));
    dom.style.setProperty("--dy", String(dy));
  }
}
